//
//  TokenViewController.swift
//  GhostWorld
//
//  Created by Kam on 2018/6/18.
//  Copyright © 2018 LKGood. All rights reserved.
//

import UIKit
import PKHUD
import SwiftyStoreKit

private let tokenCellIdentifier = "TokenCell"
private let tokenHeaderIdentifier = "TokenHeader"
private let tokenFooterIdentifier = "TokenFooter"

class TokenViewController: BaseViewController {
  
  // MARK: - IBOutlets
  
  @IBOutlet private weak var collectionView: UICollectionView!
  
  // MARK: - Private vars
  
  private var isFirstLoaded = true
  private var tokensArray: [Token]?
  private var myTokenCounts = 0
  private var selectedToken: Token?
  
  private var header: TokenHeaderView?
  
  private var informationType: InformationType = .unknown
  
  // MARK: - Private methods
  
  private func loadData() {
    API.shared.requestAPI (
      APIURLStrings.allTokens,
      method: .get,
      header: API.shared.memeberHeader,
      successCallback: { json in
      
      if let tokensJSON = json["coins"].array {
        self.tokensArray = tokensJSON.map {
          Token (
            id: $0["id"].intValue,
            name: $0["name"].stringValue,
            count: $0["count"].intValue,
            price: $0["price"].intValue,
            description: $0["description"].stringValue,
            iapIdentifier: $0["iap_identifier"].stringValue
          )
        }
        self.collectionView.reloadData()
        if let count = self.tokensArray?.count, count > 0 {
          self.collectionView.selectItem (
            at: IndexPath(row: 0, section: 0),
            animated: true,
            scrollPosition: .bottom
          )
          self.selectedToken = self.tokensArray?.first
        }
      }
      
      let myTokenCountsJson = json["my_total_coins"]
      self.myTokenCounts = myTokenCountsJson.intValue
      
      UIView.animate(withDuration: 0.3) {
        self.collectionView.alpha = 1
      }
      
    }) { (message, code) in
      loggingPrint("[\(code)]: \(message)")
    }
  }
  
  private func addNotifications() {
    NotificationCenter.default.addObserver (
      self,
      selector: #selector(updateListenerTokenCount(notification:)),
      name: .uploadTokenPurchaseInfoSuccess,
      object: nil
    )
  }
  
  @objc private func updateListenerTokenCount(notification: Notification) {
    if let userInfo = notification.userInfo,
      let object = userInfo[UploadTokenPurchaseInfoNotificationObject.key] as? UploadTokenPurchaseInfoNotificationObject {
      myTokenCounts = object.listenerTotalTokenCount
      header?.totalTokenCounts = myTokenCounts
    }
  }
  
  private func displayInformation(type: InformationType) {
    informationType = type
    performSegue(withIdentifier: "ShowInformationSegue", sender: self)
  }
  
  // MARK: - Public vars
  
  
  
  // MARK: - Lifecycle
  
  override func viewDidLoad() {
    super.viewDidLoad()
    
    addNotifications()
    loadData()
  }
  
  override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    
    if isFirstLoaded {
      collectionView.alpha = 0
    }
  }
  
  override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    
    if isFirstLoaded {
      isFirstLoaded = false
    }
  }
  
  override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "ShowInformationSegue" {
      let informationViewController = segue.destination as! InformationViewController
      informationViewController.informationType = informationType
    }
  }
  
  override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
  }
  
  deinit {
    NotificationCenter.default.removeObserver(self)
  }
}

// MARK: - UICollectionViewDataSource

extension TokenViewController: UICollectionViewDataSource {
  
  func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 1
  }
  
  func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return tokensArray?.count ?? 0
  }
  
  func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: tokenCellIdentifier, for: indexPath) as! TokenCell
    
    if let token = tokensArray?[indexPath.row] {
      cell.prepare(token: token)
    }
    return cell
  }
  
  func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
    if kind == UICollectionView.elementKindSectionHeader {
      let header = collectionView.dequeueReusableSupplementaryView (
        ofKind: kind,
        withReuseIdentifier: tokenHeaderIdentifier, for: indexPath) as! TokenHeaderView
      header.totalTokenCounts = myTokenCounts
      self.header = header
      return header
    } else if kind == UICollectionView.elementKindSectionFooter {
      let footer = collectionView.dequeueReusableSupplementaryView (
        ofKind: kind,
        withReuseIdentifier: tokenFooterIdentifier, for: indexPath) as! TokenFooterView
      footer.delegate = self
      return footer
    } else {
      return UICollectionReusableView()
    }
  }
}

// MARK: - UICollectionViewDelegate

extension TokenViewController: UICollectionViewDelegate {
  
  func collectionView(_ collectionView: UICollectionView, shouldHighlightItemAt indexPath: IndexPath) -> Bool {
    return true
  }
  
  func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    selectedToken = tokensArray?[indexPath.row]
  }
}

extension TokenViewController: UICollectionViewDelegateFlowLayout {
  
  func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: (collectionView.width - 32) / 2 - 8, height: TokenCell.defaultHeight)
  }
  
  func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
    if section == 0 {
      return CGSize(width: collectionView.width, height: TokenHeaderView.defaultHeight)
    } else {
      return CGSize.zero
    }
  }
  
  func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
    if section == 0 {
      return CGSize(width: collectionView.width, height: TokenFooterView.defaultHeight)
    } else {
      return CGSize.zero
    }
  }
}

extension TokenViewController: TokenFooterViewDelegate {
  func purchase() {
    HUD.show(.labeledProgress(title: "请稍后", subtitle: nil))
    if let token = selectedToken {
      SwiftyStoreKit.purchaseProduct(token.iapIdentifier) { result in
        switch result {
        case .success(let product):

          HUD.flash(.labeledSuccess(title: "购买成功", subtitle: nil), delay: 1.5)

          let transaction = product.transaction
          let transactionIdentifier = transaction.transactionIdentifier!
          let transactionDict: [String : Any] = [
            "id": transaction.transactionIdentifier!,
            "date": transaction.transactionDate!.toString(format: .dateTime),
            "state": transaction.transactionState.rawValue
            ]
          var jsonString = ""
          do {
            let jsonData = try JSONSerialization.data (
              withJSONObject: transactionDict,
              options: .prettyPrinted
            )
            jsonString = String(data: jsonData, encoding: .utf8)!
          } catch {  }

          PurchaseUploadData.save (
            platform: .iap,
            type: .token,
            refID: token.id,
            transactionJSON: jsonString,
            transactionID: transactionIdentifier
          )
          PurchaseUploader.shared.upload()

        case .error(let error):
          var title = "购买失败"
          var message = "请重试"
          switch error.code {
          case .unknown:
            print("Unknown error. Please contact support")
            title = "未知错误"
          case .clientInvalid:
            print("Not allowed to make the payment")
          case .paymentCancelled:
            print("User cancelled the payment")
            title = "已取消购买"
            message = ""
          case .paymentInvalid:
            print("The purchase identifier was invalid")
          case .paymentNotAllowed:
            print("The device is not allowed to make the payment")
            title = "没有购买权限"
          case .storeProductNotAvailable:
            print("The product is not available in the current storefront")
            title = "内购不可用"
          case .cloudServicePermissionDenied:
            print("Access to cloud service information is not allowed")
          case .cloudServiceNetworkConnectionFailed:
            title = "网络连接失败"
            print("Could not connect to the network")
          case .cloudServiceRevoked:
            print("User has revoked permission to use this cloud service")
            
          default:break
          }
          
          HUD.flash(.labeledError(title: title, subtitle: message), delay: 1.5)
        }
      }
      
      // MARK: - Alipay
//      API.shared.requestAPI (
//        APIURLStrings.getTokenAlipayURL(tokenIdentifier: token.id),
//        method: .get,
//        header: API.shared.memeberHeader,
//        successCallback: { json in
//          if json["order"].exists() {
//            HUD.hide()
//            let order = json["order"].stringValue
//            AlipayManager.shared.refIdentifier = token.id
//            AlipaySDK.defaultService().payOrder(order, fromScheme: "GhostWorld", callback: { response in
//              // handle no-alipay-app-response
//              AlipayManager.shared.process (
//                orderResponse: response,
//                completion: { (success, message) in
//                  if success {
//                    HUD.flash(.labeledSuccess(title: message, subtitle: nil), delay: 1.5)
//                  } else {
//                    HUD.flash(.labeledError(title: message, subtitle: nil), delay: 1.5)
//                  }
//              })
//            })
//          } else {
//            HUD.flash(.labeledError(title: "购买信息获取失败", subtitle: nil), delay: 1.5)
//          }
//
//      }) { (message, code) in
//        HUD.flash(.labeledError(title: "购买信息获取失败", subtitle: nil), delay: 1.5)
//      }
      
    } else {
      HUD.flash(.labeledError(title: "请选择购买内容", subtitle: nil), delay: 1.5)
    }
  }
  
  func displayChargeInstruction() {
    displayInformation(type: .tokenRechargeInstruction)
  }
  
  func displayChargeAgreement() {
    displayInformation(type: .agreement)
  }
}
